home *** CD-ROM | disk | FTP | other *** search
- /*
- txtomw.c
-
- This is a skeleton program for converting text files into MacWrite documents.
- It is written in MPW C 2.0.2 but it should be easy to modify it so it compiles
- under other C compilers (e.g. under UNIX as someone wanted to do) if you have
- the necessary Macintosh header files.
-
- Format changes can be added to the text according to some rules. As it is, only
- one formatting code is recognized and that is a '>' to signify the beginning of
- italic text and '<' to signify the end. As I used it originally there were far
- more complex formatting codes and it should be fairly easy to add them in.
-
- Macintosh Tech Note #12 should be helpful in understanding the workings of
- the program. When needed I peeked into genuin MacWrite files and saw what
- was done. I followed very closely what MacWrite does but something of what
- my program does may be unnecessary.
-
- The code is not to heavily commented, but should (hopefully) be reasonably
- clear.
-
- If you are using MPW C 2.0.2 you can compile the file without modifications
- using these commands:
- C txtomw.c
- Link txtomw.c.o ∂
- "{CLibraries}"CRuntime.o ∂
- "{CLibraries}"StdCLib.o ∂
- "{CLibraries}"CInterface.o ∂
- -o txtomw
-
-
- I would be happy to hear from you if this is to any use to you and even
- happier if you send me the nifty improvements you make to it.
- Please feel free to pass this on to others, preferably with my name included.
-
- Gisli Runar Hjaltason
- University of Iceland
- (undergrad til ~1990)
- UUCP:
- grh@rhi.hi.is
- grh@krafla.UUCP
- BIX:
- gisli
- DELPHI:
- GISLI
- Snail mail:
- Njalsgata 12
- IS-101 Reykjavik
- ICELAND
- */
-
- /* Standard C headers */
- #include <stdio.h>
- #include <ioctl.h>
- #include <string.h>
-
- /* Macintosh headers (directly used functions and types in comments) */
- #include <types.h>
- /* Handle */
- #include <quickdraw.h>
- /* InitGraf */
- #include <fonts.h>
- /* InitFonts */
- #include <windows.h>
- /* InitWindows */
- #include <dialogs.h>
- /* InitDialogs */
- #include <resources.h>
- /* CreateResFile, OpenResFile, RmveResource, GetResource,
- AddResource, CloseResFile */
- #include <packages.h>
- /* NumToString, SFGetFile, SFReply */
- #include <memory.h>
- /* MaxApplZone */
- #include <files.h>
- /* GetFInfo, SetFInfo, Allocate, SetVol, FInfo */
- #include <osutils.h>
- /* PtrToHand */
- #include <strings.h>
- /* p2cstr */
-
- /* Note: some of these are unnecessary in MPW C because the functions used
- are not declared in the corresponding header file */
-
- /* MacWrite header */
- #include "txtomw.h"
-
- #define NEWLINE 0x0D
-
- #define BUFSIZ 4096
- #define MAXPARS 1000
- /* Maximum number of paragraphs that are to be in a single output file.
- This can be as high as 32000 but then the "pars" array takes about 512K.
- Of course I could have resized it dynamically, but I didn't... */
-
- char *getdoc();
-
- struct doc_header dhead;
- FILE *infile, *outfile;
- short outcount;
- par_info *pars;
- par_info headpars[2];
- par_info footpars[2];
- short parcount;
- format fontch[200];
- long formatcount;
- par_data *cur_par;
- ruler rul;
- long curpos, prevpos;
- long previnpos;
- char filename[64], outfilename[64];
- unsigned char *buffer;
-
- main()
- {
- register int i, j;
- short length, linelength, cursize, curstyle, curfont, staerd;
-
- InitGraf(&qd.thePort);
- InitFonts();
- InitWindows();
- InitDialogs(0);
- MaxApplZone();
-
- memset(&dhead, 0, sizeof(dhead));
- dhead.version = 6;
- dhead.ruler_display = -1;
- dhead.active_doc = -1; /* makes MacWrite recalculate line heights
- and paragraph positions */
- dhead.start_page = 1;
-
- dhead.header_paragraphs = 2;
- dhead.footer_paragraphs = 2;
- dhead.start_page = 1;
- dhead.main.start_sel = dhead.main.end_sel = 0x10000;
- dhead.main.page_number_pos = 0xFFF2001E;
- dhead.main.date_pos = 0xFFF200A6;
- dhead.main.time_pos = 0xFFF20174;
- dhead.main.unused = -1;
- dhead.main.oval_redraw = -1;
- dhead.main.active_style = -1;
- dhead.main.active_font = -1;
-
- memcpy(&dhead.header, &dhead.main, sizeof(wind_var));
- memcpy(&dhead.footer, &dhead.main, sizeof(wind_var));
-
- buffer = (unsigned char *)malloc(BUFSIZ);
- if (!buffer)
- exit();
- cur_par = (par_data *)malloc(BUFSIZ+sizeof(par_data));
- if (!cur_par)
- exit();
- pars = (par_info *)malloc(MAXPARS*sizeof(par_info));
- if (!pars)
- exit();
- memset(pars, 0, MAXPARS*sizeof(par_info));
-
- /* I assume that only one kind of ruler is needed. You should be able to
- add some more easily. */
- rul.left_margin = 4;
- rul.right_margin = 480;
- rul.just = 3;
- rul.tab_numb = 1;
- rul.spacing = 0;
- rul.indent = 4;
- rul.tab_array[0] = -460;
-
- while (1) {
- infile = fopen(getdoc(filename), "r");
-
- previnpos = 0;
- outcount = parcount = curpos = 0;
-
- curfont = times;
- cursize = 12;
- curstyle = normal;
-
- open_outfile();
-
- while (!(feof(infile))) {
- if (ftell(infile) - previnpos > 50000 || parcount >= MAXPARS) {
- /* Make a new output file if the current output file
- exceeds 50000 characters or MAXPARS paragraphs.
- The limitation of the number of characters is simply
- practical; MacWrite is slow with large files. */
-
- previnpos = ftell(infile);
-
- close_outfile();
-
- open_outfile();
- }
-
- fgets(buffer, BUFSIZ, infile);
-
- linelength = strlen(buffer);
-
- i = 0;
- while (i < linelength) {
- formatcount = 1;
- fc(fontch, 0, cursize, curstyle, curfont);
-
- for (j = 0; i < linelength; ++i) {
- switch (buffer[i]) {
-
- case '>':
- curstyle = italic;
- fc(fontch + formatcount++, j, cursize, curstyle, curfont);
- break;
-
- case '<':
- curstyle = normal;
- fc(fontch + formatcount++, j, cursize, curstyle, curfont);
- break;
-
- /* add more as needed */
-
- default:
- cur_par->text[j++] = buffer[i];
- break;
- }
- }
-
- write_par: /* jump to this label if you want to make a new paragraph in the
- middle of an input line (it's seems to me to be the cleanest
- way to break out of the 'switch' statement and the 'for' loop
- at once) */
- if (cur_par->text[j-1] != NEWLINE)
- cur_par->text[j++] = NEWLINE;
- cur_par->length = j;
- prevpos = curpos;
- length = (j + 3) & -2;
- fwrite(cur_par, length, 1, outfile);
- putw((formatcount * sizeof(format))<<16, outfile);
- fseek(outfile, -2, 1);
- /* backup 2 bytes because 'putw' puts 4 bytes
- (why isn't there a 2 byte 'put') */
- fwrite(fontch, sizeof(format), formatcount, outfile);
- curpos = prevpos + length + 2 + formatcount * sizeof(format);
-
- pars[parcount].height = 1; /* text paragraph (MacWrite will calculate
- the correct height) */
- pars[parcount].par_data = (char *)prevpos;
- pars[parcount].par_len = curpos - prevpos;
- parcount++;
- }
- }
-
- close_outfile();
- fclose(infile);
- }
- }
-
- open_outfile()
- {
- FInfo fuppl;
- short skrarnr;
- long length;
- char num[5];
- Handle sh;
-
- NumToString(++outcount, num);
- strcpy(outfilename, filename);
- strcat(strcat(outfilename, num), ".mw");
- /* name the output file with the input filename
- with a following number and suffix .mw */
- outfile = fopen(outfilename, "w");
-
- GetFInfo(outfilename, 0, &fuppl);
- fuppl.fdType = 'WORD';
- fuppl.fdCreator = 'MACA';
- SetFInfo(outfilename, 0, &fuppl);
-
- /* the following 6 statements are really unnecessary unless you have to
- open the files with Microsoft Word, even then the first statement
- should suffice (i.e. make an empty resource fork) */
- CreateResFile(outfilename);
- skrarnr = OpenResFile(outfilename);
- RmveResource(GetResource('STR ', 700));
- PtrToHand("\p etnroaisdlhcfp", &sh, 16);
- AddResource(sh, 'STR ', 700, "");
- CloseResFile(skrarnr);
-
- parcount = 1;
-
- ioctl(fileno(outfile), FIOREFNUM, &skrarnr);
- length = sizeof(dhead);
- Allocate(skrarnr, &length);
- ioctl(fileno(outfile), FIOSETEOF, length);
- fseek(outfile, sizeof(dhead), 0);
-
- /* make a ruler and an empty line for the footer and header */
-
- prevpos = ftell(outfile);
- fwrite(&rul, sizeof(rul), 1, outfile);
- curpos = prevpos + sizeof(rul);
-
- fc(fontch, 0, 12, normal, times);
-
- footpars[0].height = 0;
- footpars[0].par_data = (char *)prevpos;
- footpars[0].par_len = curpos - prevpos;
-
- prevpos = curpos;
- putw(sizeof(format), outfile);
- fwrite(fontch, sizeof(format), 1, outfile);
- curpos = prevpos + 4 + sizeof(format);
-
- footpars[1].height = 1;
- footpars[1].par_data = (char *)prevpos;
- footpars[1].par_len = curpos - prevpos;
-
- dhead.footer.info_array = (char *)prevpos;
- dhead.footer.info_length = 2 * sizeof(par_info);
-
- prevpos = curpos;
- fwrite(&rul, sizeof(rul), 1, outfile);
- curpos = prevpos + sizeof(rul);
-
- headpars[0].height = 0;
- headpars[0].par_data = (char *)prevpos;
- headpars[0].par_len = sizeof(rul);
-
- prevpos = curpos;
- putw(sizeof(format), outfile);
- fwrite(fontch, sizeof(format), 1, outfile);
- curpos = prevpos + 4 + sizeof(format);
-
- headpars[1].height = 1;
- headpars[1].par_data = (char *)prevpos;
- headpars[1].par_len = curpos - prevpos;
-
- /* and a ruler for the main part */
-
- prevpos = curpos;
- fwrite(&rul, sizeof(rul), 1, outfile);
- curpos = prevpos + sizeof(rul);
-
- pars[0].height = 0;
- pars[0].par_data = (char *)prevpos;
- pars[0].par_len = sizeof(rul);
- }
-
-
- close_outfile()
- {
- memset(buffer, 0, parcount > 2 ? parcount * 2 : 4);
- /* buffer is used for the lineheight arrays, the linheight is set
- to 0 (zero) for all paragraphs */
-
- /* now I make the paragraph info for the header and footer */
-
- prevpos = curpos;
- fwrite(buffer, 4, 1, outfile);
- curpos = prevpos + 4;
-
- dhead.footer.linheight_array = (char *)prevpos;
- dhead.footer.linheight_len = 4;
-
- prevpos = curpos;
- fwrite(footpars, sizeof(par_info), 2, outfile);
- curpos = prevpos + 2 * sizeof(par_info);
-
- dhead.footer.info_array = (char *)prevpos;
- dhead.footer.info_length = 2 * sizeof(par_info);
-
- prevpos = curpos;
- fwrite(buffer, 4, 1, outfile);
- curpos = prevpos + 4;
-
- dhead.header.linheight_array = (char *)prevpos;
- dhead.header.linheight_len = 4;
-
- prevpos = curpos;
- fwrite(headpars, sizeof(par_info), 2, outfile);
- curpos = prevpos + 2 * sizeof(par_info);
-
- dhead.header.info_array = (char *)prevpos;
- dhead.header.info_length = 2 * sizeof(par_info);
-
- /* then the paragraph info for the main part */
-
- prevpos = curpos;
- fwrite(buffer, 2, parcount, outfile);
- curpos = prevpos + parcount * 2;
-
- dhead.main.linheight_array = (char *)prevpos;
- dhead.main.linheight_len = parcount * 2;
-
- prevpos = curpos;
- fwrite(pars, sizeof(par_info), parcount, outfile);
- curpos = prevpos + parcount * sizeof(par_info);
-
- dhead.main_paragraphs = parcount;
- dhead.main.info_array = (char *)prevpos;
- dhead.main.info_length = curpos-prevpos;
-
- /* the free list is next */
-
- prevpos = curpos;
- putw(prevpos + 8, outfile);
- putw(0, outfile);
- curpos = prevpos + 8;
-
- dhead.free_list = (char *)prevpos;
- dhead.free_len = dhead.free_alloc = 8;
-
- ioctl(fileno(outfile), FIOSETEOF, ftell(outfile));
-
- /* write out the document header */
-
- rewind(outfile);
- fwrite(&dhead, sizeof(dhead), 1, outfile);
-
- fclose(outfile);
- }
-
- char *
- getdoc(heiti)
- char *heiti;
- {
- SFReply reply;
- Point pt;
-
- pt.h = pt.v = 82; /* topleft is in (82,82) */
-
- SFGetFile(&pt, 0, 0, 1, "TEXT", 0, &reply);
- if (!reply.good)
- exit();
-
- SetVol(0, reply.vRefNum);
-
- return(strcpy(heiti, p2cstr(&reply.fName)));
- }
-
-
- /* This function puts the parameters into a format run. */
-
- fc(fp, first_ch, siz, styl, fontnum)
- format *fp;
- short first_ch;
- char siz;
- char styl;
- short fontnum;
- {
- fp->begin_pos = first_ch;
- fp->size = siz;
- fp->style = styl;
- fp->font_numb = fontnum;
- }
-